#include "guish.hpp"

Shell *shell = NULL;

Shell::Shell(ClientConnection *clientConnection)
{
	this->connection = clientConnection;
	this->currentState = new ShellState();
	this->lastReportedPrompt = "$";
}

Shell::~Shell()
{
	delete currentState;
}

void Shell::initialize()
{
}

void Shell::runLoginScript(int jobid, int width, int height)
{
	runCommand(jobid, "source $HOME/.guishrc", width, height);
}

ClientConnection *Shell::getClientConnection()
{
	return connection;
}

void Shell::finishJob(int jobid, PseudoTerminal *pty, int result, ShellState *finalState)
{
	delete jobs[jobid];
	jobs.erase(jobid);
	
	// Return any leftover input that the program didn't use
	string leftover = "";
	if(pty) {
		ptyManager->readAllPty(pty);
		
		leftover = pty->getLeftoverInput();
		ptyManager->discardPty(pty);
	}
	
	// Update the shell state to that at the end of the command that finished
	delete currentState;
	currentState = finalState;
	
	updatePrompt();
	
	RPCParams jobFinishedParams;
		jobFinishedParams.set("job", jobid);
		jobFinishedParams.set("result", result);
		jobFinishedParams.set("leftover", leftover);
	connection->call("finished", &jobFinishedParams);
}

void Shell::doExit()
{
	if(connection)
		connection->doExit();
}

void Shell::runCommand(int jobid, string cmd, int termWidth, int termHeight)
{
	Job *job = new Job(this, jobid, cmd, termWidth, termHeight);
	job->begin();
	jobs[jobid] = job;
}

ShellState *Shell::getState()
{
	return currentState;
}

Job *Shell::findJob(int id)
{
	if(jobs.find(id) != jobs.end())
		return jobs[id];
	else
		return NULL;
}

void Shell::updatePrompt()
{
	if(!connection)
		return;
	string promptSpec = currentState->env.get("PS1");
	if(promptSpec=="")
		promptSpec = "[\\u@\\h \\W]\\$ ";
	
	string prompt = expandPrompt(promptSpec, currentState);
	
	if(prompt != lastReportedPrompt) {
		lastReportedPrompt = prompt;
		
		RPCParams setPromptParams;
			setPromptParams.set("text", prompt);
		clientConnection->call("prompt", &setPromptParams);
	}
}

